package cqrtplm.util;

import cqrtplm.mapper.AdvancedQueryMapper;
import cqrtplm.vo.query.AdvancedQueryConditionVO;
import cqrtplm.vo.query.AdvancedQueryConfig;
import cqrtplm.vo.query.AdvancedQueryValidator;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class AdvancedQueryUtil {

    @Resource
    AdvancedQueryMapper advancedQueryMapper;
    public List<Map<String, Object>> executeSecureQuery(AdvancedQueryConfig config,
                                                        List<AdvancedQueryConditionVO> conditions) {

        validateInput(config, conditions);

        Map<String, Object> params = buildSecureParams(conditions);

        return advancedQueryMapper.advancedQuery(config, conditions, params);
    }

    private void validateInput(AdvancedQueryConfig config, List<AdvancedQueryConditionVO> conditions) {
        if (config == null) {
            throw new SecurityException("查询配置不能为空");
        }

        if (!AdvancedQueryValidator.isValidTableName(config.getMainTable())) {
            throw new SecurityException("主表名格式不合法: " + config.getMainTable());
        }

        if (conditions != null) {
            for (AdvancedQueryConditionVO condition : conditions) {
                if (!condition.validate()) {
                    throw new SecurityException("条件验证失败: " + condition.getValidationError());
                }

                validateFieldTableCombination(condition);
            }
        }
    }

    private void validateFieldTableCombination(AdvancedQueryConditionVO condition) {
        String fullFieldName;
        if (condition.getTableAlias() != null) {
            fullFieldName = condition.getTableAlias() + "." + condition.getField();
        } else {
            fullFieldName = condition.getField();
        }

        if (AdvancedQueryValidator.containsSqlInjection(fullFieldName)) {
            throw new SecurityException("字段表组合存在安全风险: " + fullFieldName);
        }
    }

    private Map<String, Object> buildSecureParams(List<AdvancedQueryConditionVO> conditions) {
        Map<String, Object> params = new HashMap<>();

        if (conditions != null) {
            for (int i = 0; i < conditions.size(); i++) {
                AdvancedQueryConditionVO condition = conditions.get(i);
                Object value = condition.getValue();

                if (value instanceof String) {
                    value = AdvancedQueryValidator.sanitizeString((String) value);

                    if (condition.getOperator().equals("LIKE") ||
                            condition.getOperator().equals("NOT LIKE")) {
                        value = limitWildcards((String) value);
                    }
                }

                params.put("param" + i, value);
            }
        }

        return params;
    }

    private String limitWildcards(String value) {
        if (value == null) return null;

        long wildcardCount = value.chars()
                .filter(c -> c == '%' || c == '_')
                .count();

        if (wildcardCount > 5) {
            return value.replaceAll("[%_]", "");
        }

        return value;
    }
}
